package v9.assist.analyst

import android.graphics.Bitmap
import kotlinx.coroutines.script.Block
import kotlinx.coroutines.script.ROAD
import kotlinx.coroutines.script.TARGET
import kotlinx.coroutines.script.analysis.Analysis
import kotlinx.coroutines.script.SMapBase.hitDeathRed
import kotlinx.coroutines.script.SMapBase.hitEquipO
import kotlinx.coroutines.script.SMapBase.hitSMapEnemyBlue
import kotlinx.coroutines.script.SMapBase.hitSMapEnemyYellow
import kotlinx.coroutines.script.SMapBase.hitTeammate
import kotlinx.coroutines.script.step
import kotlinx.coroutines.script.tes.ColorDiffer
import kotlinx.coroutines.script.tes.printLog
import kotlinx.coroutines.script.tes.pt
import kotlinx.coroutines.script.tes.rgb
import kotlinx.coroutines.script.tes.shake
import v9.assist.script.sLastFeature30Ts
import v9.assist.script.xBossBesideTs
import v9.assist.script.xLastAtkTs
import v9.assist.script.xLastPetBlacksmithTs
import v9.assist.script.xLastReviveTs
import v9.assist.script.xLastSceneEnterTs
import v9.assist.script.xLastUnknownTs
import kotlin.math.abs
import kotlin.math.tan

private val hitRoad by lazy { // 21-28
    val out = mutableSetOf<ColorDiffer>()
    out.addAll(setOf(0xff3c3b33.toInt().rgb(14))) //辅路
    out.addAll(setOf(0xff454137.toInt().rgb(14))) //主径
    out.addAll(hitPrimaryRoad)
    out
}
private val hitPrimaryRoad by lazy {
    val out = mutableSetOf<ColorDiffer>()
    out.addAll(setOf(0xff454137.toInt().rgb(2)))  //主径
    out.addAll(hitEquipO)
    out.addAll(hitDeathRed)
    out.addAll(hitTeammate)
    out.addAll(hitSMapEnemyYellow)
    out.addAll(hitSMapEnemyBlue)
    out
}

var anaLastCrossPointAchievedTs = 0L //接近npc
private var anaLastCrossPointCompletedTs = 0L //接近完毕
private var anaCounterAchievedCrossPoint = 0
//private var anaLastSMapTargetPTTs = 0L // primary top
//var anaLastSMapTargetRTTs = 0L // random top
//private var anaLastSMapBeforeBossTopTs = 0L

var anaLastSMapSMFeature1Ts = 0L // 右上角死路检测A
var anaLastSMapSMFeature2Ts = 0L // 右上角死路检测B
//var anaLastSMapSMFeature3Ts = 0L // Boss前顶端
var anaLastSMapSMFeature4Ts = 0L // 副本外
var anaLastSMapSMFeature5Ts = 0L // npc上侧
var anaLastSMapSMFeature6Ts = 0L // 即将到npc对话流程
var anaLastSMapSMFeature7Ts = 0L //
var anaLastSMapSMFeature8Ts = 0L //
var anaLastSMapSMFeature9Ts = 0L // 直通特征
//var anaLastSMapSMFeature10Ts = 0L // Boss前正下
//var anaLastSMapSMFeature11Ts = 0L // Boss前门口
var anaLastSMapSMFeature12Ts = 0L // randomLeft
var anaLastSMapSMFeature13Ts = 0L // Boss前下右

fun rasterizeMapSM(ss: Bitmap): Array<IntArray> {
    return rasterizeMap(ss, hitRoad, hitPrimaryRoad, filterEnemyY = false, filterRedDot = false)
}

fun analysisMapSM(ss: Bitmap) {
//    printLog { "analysisMapSM" }
    analysisMapElements(ss)
    val returnMapArray = rasterizeMapSM(ss)

    if (blockEliteEnemyBoss != null && mapEnemyList.isNotEmpty()) {
        // 优先Boss
        mapTargetList.add(mapEnemyList.random())
        printLog { "analyst target to boss" }
        lastSMapTargetToBossTs = System.currentTimeMillis()
        if (mapElementDistance(blockEliteEnemyBoss) < 30.pt) xBossBesideTs = System.currentTimeMillis()
    } else if (mapEnemyList.isNotEmpty()
        && System.currentTimeMillis() - anaLastPageSceneEnterTs > 10000 // 刚开局就需要
        && System.currentTimeMillis() - anaLastSceneSettleTs > 20000
        && !bsSceneSettle && !bsSceneSettleBlacksmith) {
        // 优先敌人
        mapTargetList.add(mapEnemyList.random())
        printLog { "analyst target to elite enemy" }
    } else if (bsSceneSettleBlacksmith && mapBlacksmithList.isNotEmpty()) {
        mapTargetList.add(mapBlacksmithList.random())
        printLog { "analyst target to blacksmith" }
    } else if (bsSceneSettle && mapBlueDoorList.isNotEmpty()) {
        mapTargetList.add(mapBlueDoorList.random())
        printLog { "analyst target to blueDoor" }
    } else {
        if (mapPrimaryRoadList.isNotEmpty()
            && System.currentTimeMillis() - lastEliteEnemyBossTs < 6000
            && System.currentTimeMillis() - anaLastHasEnemyBossNameTs < 6000
            && System.currentTimeMillis() - xLastReviveTs > 30000) {
            printLog { "analyst target to primary by boss" }
            mapTargetList.add(mapPrimaryRoadList.random())
        } else if (takeCrossPointByPrimary(returnMapArray)) {
            printLog { "analyst target to primary cross point" }
        } else if (mapTopNotArrived.size > 0) {
            mapTargetList.add(mapTopNotArrived.random())
            printLog { "analyst target to top" }
        } else {
//            (mapSampleArrived.filter { it.second < selfInSmallMap.y - smallMap.top }
//                .randomOrNull())?.also {
//                mapTargetList.add(it)
//                printLog { "analyst target to random top" }
//                anaLastSMapTargetRTTs = System.currentTimeMillis()
//            }
            mapSampleArrived.minByOrNull { it.first }?.also {
                mapTargetList.add(it)
                printLog { "analyst target to random left" }
            }
        }
    }

    if (mapTargetList.isNotEmpty()) {
        val target = mapTargetList.random()
//        printLog { "analyst target $target" }
        returnMapArray[target.first][target.second] = TARGET
    }

    angleByRoad = analysisRasterizeMap(returnMapArray)
    angleByRoad = angleSpecialAdjust(angleByRoad ?: 40.shake(15))

    // map feature
    analysisMapSMIsStartPoint(ss)
    if ((blockBlueDoor == null || blockBlacksmith == null)
        && System.currentTimeMillis() - lastEliteEnemyBossTs > 10000) {
        printLog { "analystSM $mapSimpleStatus" }
        if (System.currentTimeMillis() - lastMapTopNotArrivedTs > 2000
            && System.currentTimeMillis() - lastMapBottomNotArrivedTs < 1000
            && System.currentTimeMillis() - lastMapLeftNotArrivedTs < 1000
            && System.currentTimeMillis() - lastMapRightNotArrivedTs > 2000
            && lastMapTopP == null
            && (lastMapBottomP ?: -1f) in 0.05 .. 0.26
            && (lastMapLeftP ?: -1f) in 0.65 .. 0.87
            && lastMapRightP == null
        ) {
            // [上(64s,c:0][下(0s,0.13841808,c:46][左(0s,0.8076923,c:34][右(100s,c:0]]
            // [上(6s,c:0][下(0s,0.13841808,c:46][左(0s,0.8247863,c:30][右(126s,c:0]]
            // [上(11s,c:0][下(0s,0.2457627,c:56][左(0s,0.6962251,c:48][右(1737200211s,c:0]]
            printLog { "analystSM 节点.死路检测A" }
            anaLastSMapSMFeature1Ts = System.currentTimeMillis()
        } else if (System.currentTimeMillis() - lastMapTopNotArrivedTs < 1000
            && System.currentTimeMillis() - lastMapBottomNotArrivedTs < 1000
            && System.currentTimeMillis() - lastMapLeftNotArrivedTs < 1000
            && System.currentTimeMillis() - lastMapRightNotArrivedTs > 2000
            && (lastMapTopP ?: -1f) in 0.01 .. 0.14
            && (lastMapBottomP ?: -1f) in 0.15 .. 0.30
            && (lastMapLeftP ?: -1f) in 0.20 .. 0.45
            && lastMapRightP == null ) {
            // [上(0s,0.079209045,c:25][下(0s,0.22881356,c:74][左(0s,0.25065032,c:46][右(160s,c:0]]
            // [上(0s,0.07356915,c:23][下(0s,0.24895602,c:69][左(0s,0.3948949,c:74][右(189s,c:0]]
            printLog { "analystSM 节点.死路检测B" }
            anaLastSMapSMFeature2Ts = System.currentTimeMillis()
        } else if (System.currentTimeMillis() - lastMapTopNotArrivedTs > 2000
            && System.currentTimeMillis() - lastMapLeftNotArrivedTs > 2000
            && System.currentTimeMillis() - lastMapRightNotArrivedTs > 2000
            && lastMapTopP == null
            && (lastMapBottomP == null || (lastMapBottomP ?: -1f) in 0.47 .. 0.61)
            && lastMapBottomC < 15
            && lastMapRoadC < 12 // 实际2-9
            && lastMapLeftP == null
            && lastMapRightP == null
            && System.currentTimeMillis() - xLastAtkTs > 4000
            && System.currentTimeMillis() - lastEliteEnemyBossTs > 12000) {
            // [上(168s,c:0][下(0s,0.5451977,c:10][左(168s,c:0][右(308s,c:0]]
            // [上,10s,c:0][下,6s,c:0][左,7s,c:0][右,1741870611s,c:0]][Road,c:7]
            // [上,26s,c:0][下,0s,0.579096,c:1][左,9s,c:0][右,142s,c:0]][Road,c:0]
            printLog { "analystSM 节点.副本外入口" } // or boss maybe//  [可以用sampleCount来区分] // boss前也有这个
            anaLastSMapSMFeature4Ts = System.currentTimeMillis()
            anaClearSceneSettle()
        } else if (System.currentTimeMillis() - lastMapTopNotArrivedTs < 1000
            && System.currentTimeMillis() - lastMapBottomNotArrivedTs < 1000
            && System.currentTimeMillis() - lastMapLeftNotArrivedTs < 1000
            && System.currentTimeMillis() - lastMapRightNotArrivedTs < 1000
            && (lastMapTopP ?: -1f) in 0.15 .. 0.25
            && (lastMapBottomP ?: -1f) in 0.40 .. 0.54
            && (lastMapLeftP ?: -1f) in 0.05 .. 0.20
            && (lastMapRightP ?: -1f) in 0.25 .. 0.35
            && System.currentTimeMillis() - lastBlueDoorTs > 5000
            && System.currentTimeMillis() - lastBlacksmithTs > 5000) {
            // [上(0s,0.20907934,c:71][下(0s,0.5131827,c:72][左(0s,0.10042735,c:8][右(0s,0.29008546,c:25]]
            // [上(0s,0.20907934,c:71][下(0s,0.53260165,c:61][左(0s,0.14102565,c:20][右(0s,0.30899292,c:23]]
            printLog { "analystSM 节点.npc上侧" }
            anaLastSMapSMFeature5Ts = System.currentTimeMillis()
        } else if (System.currentTimeMillis() - lastMapTopNotArrivedTs < 1000
            && System.currentTimeMillis() - lastMapBottomNotArrivedTs < 1000
            && System.currentTimeMillis() - lastMapLeftNotArrivedTs < 1000
            && (lastMapTopP ?: -1f) in 0.65 .. 0.75
            && (lastMapBottomP ?: -1f) in 0.08 .. 0.18
            && (lastMapLeftP ?: -1f) in 0.85 .. 0.95
            && System.currentTimeMillis() - lastBlueDoorTs > 5000
            && System.currentTimeMillis() - lastBlacksmithTs > 5000
            && System.currentTimeMillis() - anaLastSMapSMFeature5Ts > 10000) { // 从上测触发到这个.然后又由于长时间回到起点了
            // [上,0s,0.72640204,c:82][下,0s,0.13565598,c:45][左,0s,0.88461536,c:14][右,19s,c:0]][Road,c:53]
            // [上,0s,0.72827715,c:79][下,0s,0.17231639,c:52][左,0s,0.92246646,c:7][右,0s,0.06125356,c:3]][Road,c:41]
            // [上,0s,0.7007393,c:81][下,0s,0.10451978,c:34][左,0s,0.8630443,c:21][右,4s,c:0]][Road,c:51]
            printLog { "analystSM 节点.即将到npc对话流程" }
            anaLastSMapSMFeature6Ts = System.currentTimeMillis()

        } else if (System.currentTimeMillis() - lastMapTopNotArrivedTs < 1000
            && System.currentTimeMillis() - lastMapBottomNotArrivedTs > 2000
            && System.currentTimeMillis() - lastMapLeftNotArrivedTs > 2000
            && (lastMapTopP ?: -1f) in 0.72 .. 0.86
            && lastMapBottomP == null
            && lastMapLeftP == null
            && (lastMapRightP == null || (lastMapRightP ?: -1f) in 0.00 .. 0.10)
            && System.currentTimeMillis() - xLastAtkTs > 4000
            && System.currentTimeMillis() - lastBlueDoorTs < 2000
            && System.currentTimeMillis() - xLastUnknownTs > 6000
            && System.currentTimeMillis() - xLastSceneEnterTs > 8000
        ) {
            printLog { "analystSM 节点.直通" }
            // [上,0s,0.8220339,c:54][下,1741870319s,c:0][左,1741870319s,c:0][右,0s,c:0]][Road,c:25]
            // [上,0s,0.8530497,c:49][下,1741870289s,c:0][左,1741870289s,c:0][右,0s,0.06410257,c:2]][Road,c:26]
            // [上,0s,0.7707519,c:52][下,91s,c:0][左,1737470545s,c:0][右,23s,c:0]][Road,c:22]
            anaLastSMapSMFeature9Ts = System.currentTimeMillis()
        } else if (System.currentTimeMillis() - lastMapLeftNotArrivedTs > 2000
            && (lastMapTopP == null || (lastMapTopP ?: -1f) in 0.65 .. 0.75)
            && (lastMapBottomP ?: -1f) in 0.80 .. 0.94
            && lastMapLeftP == null
            && (lastMapRightP == null || (lastMapRightP ?: -1f) in 0.84 .. 0.98)
            && System.currentTimeMillis() - xLastUnknownTs > 6000
            && System.currentTimeMillis() - xLastSceneEnterTs > 15000
        ) {
            printLog { "analystSM 节点.Boss前门Left" }
            // [上,0s,0.7011299,c:5][下,0s,0.89774007,c:25][左,245s,c:0][右,0s,0.93978244,c:11]][Road,c:44]
            // [上,2s,c:0][下,0s,0.85286516,c:35][左,401s,c:0][右,1s,c:0]][Road,c:31]
            // [上,10s,c:0][下,0s,0.8273305,c:32][左,410s,c:0][右,9s,c:0]][Road,c:25]
            // [上,0s,0.71171576,c:19][下,0s,0.9237288,c:16][左,417s,c:0][右,0s,0.8956044,c:21]][Road,c:46]
            // [上,0s,0.6912833,c:14][下,0s,0.90947,c:21][左,1741184793s,c:0][右,0s,0.922792,c:15]][Road,c:46]
            //  [上,0s,0.720339,c:6][下,0s,0.90112996,c:24][左,1741184960s,c:0][右,0s,0.9482431,c:9]][Road,c:45]
            anaLastSMapSMFeature12Ts = System.currentTimeMillis()
        } else if (System.currentTimeMillis() - lastMapTopNotArrivedTs > 2000
            && System.currentTimeMillis() - lastMapBottomNotArrivedTs < 1000
            && System.currentTimeMillis() - lastMapLeftNotArrivedTs < 1000
            && System.currentTimeMillis() - lastMapRightNotArrivedTs > 2000
            && lastMapTopP == null
            && (lastMapBottomP ?: -1f) in 0.36 .. 0.44
            && (lastMapLeftP ?: -1f) in 0.44 .. 0.56
            && lastMapLeftC < 6
            && lastMapRightP == null
            && System.currentTimeMillis() - xLastUnknownTs > 6000
            && System.currentTimeMillis() - xLastSceneEnterTs > 15000
        ) {
            printLog { "analystSM 节点.Boss前门下右" }
            // [上,28s,c:0][下,0s,0.41011813,c:33][左,0s,0.6923077,c:1][右,21s,c:0]][Road,c:53]
            anaLastSMapSMFeature13Ts = System.currentTimeMillis()
        }
    }

    if (System.currentTimeMillis() - anaLastPageSceneEnterTs > 8000
        && System.currentTimeMillis() - xLastUnknownTs > 8000
        && System.currentTimeMillis() - anaLastHasEnemyNameTs > 4000
        && System.currentTimeMillis() - lastEliteEnemyBossTs > 4000
        && blockBlueDoor != null
        && blockBlacksmith != null
        && !bsSceneSettle && !bsSceneSettleBlacksmith
        && simpleAssertSceneCompleted(blockBlueDoor, blockBlacksmith)) {
        printLog { "analyst scene completed count $anaCounterSceneSettle" }
        anaCounterSceneSettle++
        if (anaCounterSceneSettle > 0) {
            printLog { "analyst scene completed" }
            anaMarkSceneSettle()
        }
    }
    if (System.currentTimeMillis() - lastBlueDoorTs > 3000
        && System.currentTimeMillis() - lastBlacksmithTs > 3000) {
        anaCounterSceneSettle = 0
    }
}

private val cSMP1StartA1 by lazy { Block("神庙起点检测outA1", selfInSmallMap.x - 30.pt, selfInSmallMap.y - 60.pt, 20.pt, 20.pt) }
private val cSMP1StartA2 by lazy { Block("神庙起点检测outA2", selfInSmallMap.x + 20.pt, selfInSmallMap.y - 64.pt, 20.pt, 20.pt) }
private val cSMP1StartA3 by lazy { Block("神庙起点检测outA3", selfInSmallMap.x + 64.pt, selfInSmallMap.y - 20.pt, 40.pt, 20.pt) }
private val cSMP1StartA4 by lazy { Block("神庙起点检测outA4", selfInSmallMap.x + 30.pt, selfInSmallMap.y + 30.pt, 20.pt, 20.pt) }
 val cSMP1StartA5 by lazy { Block("神庙起点检测inA5", selfInSmallMap.x + 20.pt, selfInSmallMap.y + 5.pt, 16.pt, 16.pt) }
 val cSMP1StartA6 by lazy { Block("神庙起点检测inA6主", selfInSmallMap.x + 30.pt, selfInSmallMap.y - 32.pt, 14.pt, 14.pt) }
 val hitSMStartRoad by lazy { setOf(0xff3C392E.toInt().rgb(7),) } // 必须6 不然就掉太多了 0.8变成0.2
 val hitSMStartPrimaryRoad by lazy { setOf(0xff4A4538.toInt().rgb(6),) }

fun analysisMapSMIsStartPoint(ss: Bitmap): Boolean {
//    printLog { "analysisMapSMIsStartPoint analystSM $mapSimpleStatus" }
    if (System.currentTimeMillis() - lastMapBottomNotArrivedTs > 2000
        && System.currentTimeMillis() - lastMapLeftNotArrivedTs > 2000
        && blockBlacksmith == null
//         && blockBlueDoor != null
    ) {
        var hitPart = 0
        // hit [smP5] 1.0 hitCount 25 total 25
        // hit [smP6] 0.5625 hitCount 9 total 16
        if (!Analysis.hit(ss, cSMP1StartA1, hitSMStartRoad, 4.pt, 0.1f, )) hitPart++ // , "smP1"
        if (!Analysis.hit(ss, cSMP1StartA2, hitSMStartRoad, 4.pt, 0.1f,  )) hitPart++ // , "smP2"
        if (!Analysis.hit(ss, cSMP1StartA3, hitSMStartRoad, 4.pt, 0.1f,  )) hitPart++ // , "smP3"
        if (!Analysis.hit(ss, cSMP1StartA4, hitSMStartRoad, 4.pt, 0.1f, )) hitPart++ //  "smP4"
        if (Analysis.hit(ss, cSMP1StartA5, hitSMStartRoad, 4.pt, 0.7f,   )) hitPart++ // , "smP5"
        if (Analysis.hit(ss, cSMP1StartA6, hitSMStartPrimaryRoad, 4.pt, 0.2f,  )) hitPart++ // , "smP6"
        if (hitPart >= 6) {
            printLog { "analystSM 节点.神庙路线是起点C" }
            anaLastSMapSMFeature7Ts = System.currentTimeMillis()
            anaClearSceneSettle()
            return true
        }
    }

//    if (System.currentTimeMillis() - lastMapTopNotArrivedTs < 1000
//        && System.currentTimeMillis() - lastMapBottomNotArrivedTs < 1000
//        && System.currentTimeMillis() - lastMapLeftNotArrivedTs > 2000
//        && System.currentTimeMillis() - lastMapRightNotArrivedTs < 1000
//        && (lastMapTopP ?: -1f) in 0.88 .. 0.98
//        && lastMapTopC in 10 .. 30
//        && (lastMapBottomP ?: -1f) in 0.45 .. 0.55
//        && lastMapBottomC in 1 .. 15
//        && lastMapLeftP == null
//        && (lastMapRightP ?: -1f) in 0.15 .. 0.25
//        && System.currentTimeMillis() - lastEliteEnemyBossTs > 10000
//        && blockBlacksmith == null
//        && blockBlueDoor != null) {
//        // [上,0s,0.9320689,c:21][下,0s,0.50564975,c:2][左,1737281643s,c:0][右,0s,0.2057057,c:37]][Road,c:21]
//        printLog { "analystSM 节点.神庙路线是起点B" }
//        anaLastSMapSMFeature7Ts = System.currentTimeMillis()
//        anaClearSceneSettle()
//        return true
//    } else
    if (System.currentTimeMillis() - lastMapTopNotArrivedTs < 1000
        && System.currentTimeMillis() - lastMapBottomNotArrivedTs > 2000
        && System.currentTimeMillis() - lastMapLeftNotArrivedTs > 2000
        && System.currentTimeMillis() - lastMapRightNotArrivedTs < 1000
        && (lastMapTopP ?: -1f) in 0.80 .. 0.91
        && lastMapTopC in 21 .. 41
        && lastMapBottomP == null
        && lastMapLeftP == null
        && (lastMapRightP ?: -1f) in 0.08 .. 0.15
        && lastMapRightC >= 8
        && System.currentTimeMillis() - lastEliteEnemyBossTs > 10000
        && blockBlacksmith == null
        && blockBlueDoor != null) {
        // 法墓[上,0s,0.8647391,c:34][下,1748610394s,c:0][左,1748610394s,c:0][右,0s,0.08974359,c:5]][Road,c:29]
        // [上,0s,0.88476527,c:29][下,118s,c:0][左,118s,c:0][右,0s,0.123154625,c:11]][Road,c:24]
        // [上,0s,0.8456921,c:40][下,1746156280s,c:0][左,1746156280s,c:0][右,0s,0.11063628,c:9]][Road,c:25]
        // [上,0s,0.88476527,c:29][下,1748859414s,c:0][左,1748859414s,c:0][右,0s,0.11063628,c:9]][Road,c:23]
        // [上,0s,0.88476527,c:29][下,1748859194s,c:0][左,1748859194s,c:0][右,0s,0.11063628,c:9]][Road,c:23]

        printLog { "analystSM 节点.神庙路线是起点A" }
        anaLastSMapSMFeature7Ts = System.currentTimeMillis()
        anaClearSceneSettle()
        return true
    }
    return false
}

private fun simpleAssertSceneCompleted(blueDoor: Block?, blacksmith: Block?): Boolean {
    if (blueDoor == null) return false
    if (blacksmith == null) return false
    val edge = 80.pt
    return (abs(blueDoor.x - blacksmith.x) < edge && abs(blueDoor.y - blacksmith.y) < edge)

}

private fun calculateIntersectionPoint( // 这个坐标轴定义. x轴正方形0度. y轴正方向90度
    x1: Int, y1: Int, x2: Int, y2: Int
): Pair<Int, Int> {
    val angle1 = Math.toRadians(55.0)
    val angle2 = Math.toRadians(140.0)
    // 计算两条线段的斜率
    val slope1 = tan(angle1)
    val slope2 = tan(angle2)
    // 计算两条线段的截距
    val intercept1 = y1 - slope1 * x1
    val intercept2 = y2 - slope2 * x2
    // 计算交点坐标
    val intersectionX = (intercept2 - intercept1) / (slope1 - slope2)
    val intersectionY =   slope1 * intersectionX + intercept1// 怎么答案是-50；；；(201, 3) (327, 3) -》 264.0 -49.86
    return intersectionX.toInt() to intersectionY.toInt()
}

private fun findRoadPoint(
    returnMapArray: Array<IntArray>,
    point: Pair<Int, Int>,
): Pair<Int, Int>? {
    // 扩大一圈的所有方向
    val directions = listOf(
        Pair(-2, -2), Pair(-2, -1), Pair(-2, 0), Pair(-2, 1), Pair(-2, 2),  // top-left to top-right
        Pair(-1, -2), Pair(-1, -1), Pair(-1, 0), Pair(-1, 1), Pair(-1, 2),  // left to right
        Pair(0, -2), Pair(0, -1), Pair(0, 0), Pair(0, 1), Pair(0, 2),  // center to right
        Pair(1, -2), Pair(1, -1), Pair(1, 0), Pair(1, 1), Pair(1, 2),  // bottom-left to bottom-right
        Pair(2, -2), Pair(2, -1), Pair(2, 0), Pair(2, 1), Pair(2, 2)   // bottom-left to bottom-right
    )
    for (dir in directions) {
        val x = point.first + dir.first
        val y = point.second + dir.second
        // 检查坐标是否在数组范围内
        if (x in returnMapArray.indices && y in returnMapArray[x].indices) {
            if (returnMapArray[x][y] == ROAD) {
                return Pair(x, y)  // 找到道路点
            }
        }
    }
    return null  // 没有找到道路点
}

private fun takeCrossPointByPrimary(returnMapArray: Array<IntArray>): Boolean {
    val pointLeftTop = mapPrimaryRoadList.filter { it.second < step + step }.minByOrNull { it.first }
    val pointRight = mapPrimaryRoadList.filter { it.first > smallMap.width - step * 8 && it.second < smallMap.height / 2 }.minByOrNull { it.second }
        ?: mapPrimaryRoadList.filter { it.second < step + step }.maxByOrNull { it.first }
    if (pointLeftTop != null && pointRight != null
        && pointRight.first - pointLeftTop.first > 30.pt
        && System.currentTimeMillis() - anaLastCrossPointCompletedTs > 20000) {
        val crossPoint = findRoadPoint(returnMapArray, calculateIntersectionPoint(pointLeftTop.first, pointLeftTop.second, pointRight.first, pointRight.second))
        if (crossPoint != null && crossPoint.first < returnMapArray.size && crossPoint.first >= 0
            && crossPoint.second < returnMapArray[0].size && crossPoint.second >= 0) {
            mapTargetList.add(crossPoint)
            val achieved = abs(crossPoint.first - smallMap.width / 2) < 30.pt && abs(crossPoint.second - smallMap.height / 2) < 30.pt
            if (achieved) {
                anaLastCrossPointAchievedTs = System.currentTimeMillis()
                anaCounterAchievedCrossPoint++
                printLog { "analyst target 已接近npc $anaCounterAchievedCrossPoint" }
                if (anaCounterAchievedCrossPoint >= 5
                    || (anaCounterAchievedCrossPoint >= 3 && System.currentTimeMillis() - xLastAtkTs > 4000)  // 已经靠近过npc且周围没有怪
                    || (anaCounterAchievedCrossPoint >= 0 && System.currentTimeMillis() - xLastReviveTs < 30000)
                ) { // 被击杀回去 // 放行
                    printLog { "analyst target 放行" }
                    anaCounterAchievedCrossPoint = 0
                    anaLastCrossPointCompletedTs = System.currentTimeMillis()
                }
            }
        }
    }
    return mapTargetList.isNotEmpty()
}

private fun angleSpecialAdjust(angle: Int): Int {
    if (System.currentTimeMillis() - anaLastHasEnemyBossNameTs in 2500 .. 16000
        && System.currentTimeMillis() - lastEliteEnemyBossTs < 1000
        && System.currentTimeMillis() - xLastAtkTs < 4000) {
        printLog { "analystSM 躲避最终Boss秒杀" }
        return (angle + 180.shake(80)) % 360 // 往左外偏
    }

    if (System.currentTimeMillis() - anaLastHasEnemyBossNameTs > 3000
        && System.currentTimeMillis() - lastEliteEnemyTs > 3000
        && System.currentTimeMillis() - lastEliteEnemyBossTs > 3000
        && System.currentTimeMillis() - xLastAtkTs < 600
        && System.currentTimeMillis() - sLastFeature30Ts > 1600) {
        printLog { "analystSM 回撤清理漏怪" }
        sLastFeature30Ts = System.currentTimeMillis()
        return (angle + 180) % 360
    }

    if (angle in 95 .. 280) {
        if (System.currentTimeMillis() - xLastAtkTs > 5000
            && System.currentTimeMillis() - lastEliteEnemyBossTs > 5000
            && System.currentTimeMillis() - lastEliteEnemyTs > 5000
            && System.currentTimeMillis() - anaLastPageTalkNpcTs > 20000
            && System.currentTimeMillis() - xLastSceneEnterTs > 30000
            && System.currentTimeMillis() - xLastPetBlacksmithTs > 20000
            && System.currentTimeMillis() - xLastUnknownTs < 20000) {
            printLog { "analystSM angleSpecialAdjust $angle to 45" }
            return 45
        }
    }
    return angle
}
